package futbol.tacticas.concursantes.TacticaSanto;

import futbol.tacticas.*;
import futbol.tacticas.concursantes.Tactica;
import java.awt.*;
import java.util.*;

public class TacticaSanto implements Tactica {
	private int J1 = 0;
	private int J2 = 1;
	private int J3 = 2;
	private int J4 = 3;
	private int J5 = 4;
	private int J6 = 5;
	private int J7 = 6;
	private int J8 = 7;
	private int J9 = 8;
	private int J10 = 9;
	private int J11 = 10;
	Random rand = new Random();
	private int[][] velocidades = new int[11][2];

	int arr_x[][] = new int[11][2];
	int arr_y[][] = new int[11][2];
	int arr_p[][] = new int[11][2];
	double variable1, variable0, variable_auxiliar1, variable_auxiliar0;
	int variable_z0 = 0, variable_z1 = 0, variable_z2 = 0, variable_h0 = 0,
			variable_h1 = 0, variable_h2 = 0, _variable_z1, _variable_h1,
			_variable_z0, _variable_h0, v;
	int _bx, _by, c, _c0 = 0;
	int bx[], by[];

	Point spain[] = new Point[11];
	Vector vector_jugadas = new Vector();
	Point[][] ximple_jugada = new Point[11][2];
	boolean boo_lean2 = true, boo_lean3 = false;
	boolean boo_lean4;

	public Color getColor1() {
		return new Color(0, 0, 128);
	}

	public Color getColor2() {
		return new Color(0, 0, 128);
	}

	public Color getColorNumero() {
		return Color.WHITE;
	}

	public String getNombre() {
		return "Santos";
	}

	private int nValores[][] = { { -140, 15, 7 }, // jugador1
			{ -140, -15, 7 },// jugador2
			{ -60, 60, 6 },// jugador3
			{ -60, -60, 6 }, // jugador4
			{ 0, 20, 6 },// jugador5
			{ 0, -20, 6 }, // jugador6
			{ 50, 50, 7 },// jugador7
			{ 50, -50, 7 }, // jugador8
			{ 100, 80, 7 },// jugador9
			{ 120, 0, 7 },// jugador10
			{ 100, -80, 7 } // jugador11
	};

	public int getFuerza(int n) {
		velocidades[n][0] = 10 - nValores[n][2];
		return nValores[n][2];
	}

	public int getVelocidad(int n, int constante) {
		return velocidades[n][constante];
	}

	/*
	 * devuelve_posicionX_del_jugador_n
	 */
	public int getXInicial(int n) {
		return nValores[n][0];
	}

	/*
	 * devuelve_posicionY_del_jugador_n
	 */
	public int getYInicial(int n) {
		return nValores[n][1];
	}

	/*
	 * devuelve_angulo_de_dos_coordenadas
	 */
	private double anguloDosC(double x1, double y1, double x0, double y0) {
		return angulo(x1 - x0, y1 - y0);
	}

	/*
	 * devuelve_angulo_de_una_coordenada
	 */
	private double angulo(double x, double y) {
		double angulo = 0;
		if (x > 0 && y > 0) {
			/*
			 * primer_cuadrante
			 */
			angulo = Math.atan(y / x);// devuelve_angulo_tangente_entre_x_y
		} else {
			if (x < 0 && y > 0) {
				/*
				 * segundo_cuadrante
				 */
				angulo = Math.atan(y / x) + Math.PI;// Math.PI=180º
			} else {
				if (x > 0 && y < 0) {
					/*
					 * tercer_cuadrante
					 */
					angulo = Math.PI * 2 + Math.atan(y / x);
				} else {
					/*
					 * cuarto_cuadrante
					 */
					angulo = Math.PI + Math.atan(y / x);
				}
			}
		}
		return angulo;

	}

	/*
	 * devuelve_distancia_entre_dos_coordenadas
	 */
	private double distanciaDosC(double x1, double y1, double x0, double y0) {
		double nuevo_x = (x1 - x0);
		double nuevo_y = (y1 - y0);
		return dist_simple(nuevo_x, nuevo_y);
	}

	/*
	 * devuelve_distancia_de_coordenada
	 */
	private double dist_simple(double x, double y) {
		return Math.sqrt(x * x + y * y);
	}

	public Vector<Comando> getComandos(SituacionJugadores sj) {
		vector_jugadas.clear();
		boo_lean3 = false;
		for (int i = 0; i < 11; i++) {
			spain[i] = ximple_jugada[i][1];
			ximple_jugada[i][0] = sj.getMisJugadores()[i];
			ximple_jugada[i][1] = sj.getContrario()[i];
		}
		variable_z2 = variable_z1;
		variable_h2 = variable_h1;
		boo_lean4 = false;

		if (boo_lean4) {
			variable_z0 = _variable_z0;
			variable_h0 = _variable_h0;
		}

		variable_z1 = variable_z0;
		variable_h1 = variable_h0;
		_variable_z1 = variable_z0;
		_variable_h1 = variable_h0;
		Point b = sj.getBola();
		variable_z0 = b.x;
		variable_h0 = b.y;
		if (Math.abs(variable_z0) >= 160 && Math.abs(variable_h0) <= 30) {
			for (int i = 0; i < 100; i++) {
				int i1 = rand.nextInt(11);
				int i2 = rand.nextInt(11);
				if (i1 != i2 && getFuerza(i1) == getFuerza(i2)) {
					int x = nValores[i1][0];
					int y = nValores[i1][1];
					nValores[i1][0] = nValores[i2][0];
					nValores[i1][1] = nValores[i2][1];
					nValores[i2][0] = x;
					nValores[i2][1] = y;
				}
			}
		}

		variable_auxiliar0 = angulo(variable_z2 - variable_z1, variable_h2
				- variable_h1);
		variable_auxiliar1 = angulo(variable_z1 - variable_z0, variable_h1
				- variable_h0);
		variable0 = distanciaDosC(variable_z1, variable_h1, variable_z0,
				variable_h0);
		variable1 = distanciaDosC(variable_z2, variable_h2, variable_z1,
				variable_h1);
		if (variable0 > 100) {
			variable0 = 0;
			variable1 = 0;
			variable_z1 = 0;
			variable_h1 = 0;
			variable_z2 = 0;
			variable_h2 = 0;
			_c0 = c - 1;
			_bx = 0;
			_by = 0;

		} else {
			if (!boo_lean2) {
				int di;
				for (int i = 0; i < 11; i++) {
					di = (int) Math.floor(distanciaDosC(ximple_jugada[i][1].x,
							ximple_jugada[i][1].y, spain[i].x, spain[i].y));
					if (velocidades[i][1] < di)
						velocidades[i][1] = di;
				}
			}
		}
		boo_lean2 = false;
		if (variable0 > 3
				&& (Math.abs(variable_auxiliar0 - variable_auxiliar1) > .20 || Math
						.abs(variable1 - variable0) > 5)) {
			_bx = variable_z1;
			_by = variable_h1;
			_c0 = c - 1;
		}
		double n = (double) (c - _c0);
		double d = distanciaDosC(variable_z0, variable_h0, _bx, _by);
		v = Math.max((int) Math.round(d / n - (n + 1d) / 2d), 0);
		_variable_z0 = _variable_z1;
		_variable_h0 = _variable_h1;
		if (v > 21) {
			if (_variable_h0 < -120) {
				_variable_h0 = -240 - _variable_h0;
			}

			if (_variable_h0 > 120) {
				_variable_h0 = 240 - _variable_h0;
			}

			if (_variable_z0 < -160) {
				_variable_z0 = -320 - _variable_z0;
			}
			if (_variable_z0 > 160) {
				_variable_z0 = 320 - _variable_z0;
			}
			boo_lean4 = true;
		}

		bx = new int[v + 1];
		by = new int[v + 1];
		bx[v] = variable_z0;
		by[v] = variable_h0;
		if (v > 0) {
			double dist = distanciaDosC(_bx, _by, variable_z0, variable_h0);
			double dx = (double) (variable_z0 - _bx) / dist;
			double dy = (double) (variable_h0 - _by) / dist;
			for (int i = v; i > 0; i--) {
				bx[i - 1] = bx[i] + (int) Math.round(dx * (double) i);
				by[i - 1] = by[i] + (int) Math.round(dy * (double) i);
				if (by[i - 1] < -120) {
					by[i - 1] = -240 - by[i - 1];
					dy = -dy;
					if (i == v) {
						_by = -240 - _by;
						variable_h0 = -240 - variable_h0;
						variable_h1 = -240 - variable_h1;
						variable_h2 = -240 - variable_h2;
					}
				}
				if (by[i - 1] > 120) {
					by[i - 1] = 240 - by[i - 1];
					dy = -dy;
					if (i == v) {
						_by = 240 - _by;
						variable_h0 = 240 - variable_h0;
						variable_h1 = 240 - variable_h1;
						variable_h2 = 240 - variable_h2;
					}
				}
				if (bx[i - 1] < -160) {
					bx[i - 1] = -320 - bx[i - 1];
					dx = -dx;
					if (i == v) {
						_bx = -320 - _bx;
						variable_z0 = -320 - variable_z0;
						variable_z1 = -320 - variable_z1;
						variable_z2 = -320 - variable_z2;
					}
				}
				if (bx[i - 1] > 160) {
					bx[i - 1] = 320 - bx[i - 1];
					dx = -dx;
					if (i == v) {
						_bx = 320 - _bx;
						variable_z0 = 320 - variable_z0;
						variable_z1 = 320 - variable_z1;
						variable_z2 = 320 - variable_z2;
					}
				}
			}
		}

		for (int i = 0; i < 11; i++) {
			int jm = Math.max(Math.min(14, v - 1), 0);
			int bx_ = sj.getMisJugadores()[i].x;
			int by_ = sj.getMisJugadores()[i].y;
			variable1 = getVelocidad(i, 0);
			arr_p[i][0] = -1;
			for (int j = jm; j > 0; j--) {
				variable0 = Math.max(0,
						distanciaDosC(bx_, by_, bx[j], by[j]) - 10d)
						/ variable1;
				if (variable0 < (v - j)) {
					arr_p[i][0] = v - j;
					arr_x[i][0] = bx[j];
					arr_y[i][0] = by[j];
					break;
				}
			}
			if (arr_p[i][0] == -1) {
				variable0 = Math.max(0,
						distanciaDosC(bx_, by_, bx[0], by[0]) - 10d)
						/ variable1;
				if ((variable0 - Math.floor(variable0)) > 0)
					variable0 = Math.floor(variable0) + 1;
				else
					variable0 = Math.floor(variable0);
				arr_p[i][0] = (int) variable0;
				arr_x[i][0] = bx[0];
				arr_y[i][0] = by[0];
			}
		}
		avivate();
		IA();
		c++;
		return vector_jugadas;
	}

	private void avivate() {
		int min = Integer.MAX_VALUE;
		for (int i = 0; i < 11; i++)
			if (arr_p[i][0] < min)
				min = arr_p[i][0];
		for (int i = 0; i < 11; i++)
			if (min == arr_p[i][0])
				vector_jugadas.add(new ComandoIrA(i, arr_x[i][0], arr_y[i][0]));
			else
				vector_jugadas.add(new ComandoIrA(i, getXInicial(i),
						getYInicial(i)));
	}

	private int dead[] = { 0, 0, 0, 0, 0, 15, 55, 107 };

	/*
	 * IA: Artificial Intelligence
	 */
	private void IA() {
		int mejor = 0;
		int px = -1000;
		if (bx.length <= 15) {
			for (int i = 0; i < 11; i++) {
				if (distanciaDosC(ximple_jugada[i][0].x, ximple_jugada[i][0].y,
						variable_z0, variable_h0) <= 10) {
					if (ximple_jugada[i][0].x < -120) {
						int[] puntaje = new int[36];

						// for(int i=0;i<360;i=i+10){

						// }
					}
					if (distanciaDosC(variable_z0, variable_h0, 160, 0) <= (dead[getFuerza(i)] + 20)) {
						vector_jugadas.add(new ComandoTiroAPuerta(i, 0));// tiro
						// al
						// arco
					} else {
						int next;
						int it = 0;
						do {
							while ((next = rand.nextInt(11)) == i)
								;
							it++;
							if (ximple_jugada[next][0].x > px) {
								px = ximple_jugada[next][0].x;
								mejor = next;
							}
						} while (ximple_jugada[mejor][0].x < ximple_jugada[i][0].x
								&& it < 100);
						int dx = ximple_jugada[mejor][0].x;
						int dy = ximple_jugada[mejor][0].y;
						double dist = distanciaDosC(dx, dy, variable_z0,
								variable_h0);
						int fuerza;
						if (dist > 90)
							fuerza = 7;
						else if (dist > 40)
							fuerza = 6;
						else
							fuerza = 4;
						vector_jugadas.add(golpear(i,
								ximple_jugada[mejor][0].x,
								ximple_jugada[mejor][0].y, fuerza));
					}
				}
			}
		}
	}

	private ComandoGolpearBola golpear(int nJug, int x, int y, int fuerza) {
		double dx = x - ximple_jugada[nJug][0].x;
		double dy = y - ximple_jugada[nJug][0].y;
		if (dx != 0 && dy != 0) {
			double dist = dist_simple(dx, dy);
			dx = dx / dist;
			dy = dy / dist;
			int f = Math.min(getFuerza(nJug), fuerza);
			double d = 50d * (double) f / (double) getFuerza(nJug);
			double dd = d, ddx = dx, ddy = dy;
			int ff;
			do {
				dx = (int) ((double) ddx * dd);
				dy = (int) ((double) ddy * dd);
				dist = dist_simple(dx, dy);
				ff = getFuerza(nJug) * (int) dist / 52;
				dd++;
			} while (ff < f);
			return new ComandoGolpearBola(nJug, ximple_jugada[nJug][0].x + dx,
					ximple_jugada[nJug][0].y + dy);
		} else
			return new ComandoGolpearBola(nJug, ximple_jugada[nJug][0].x,
					ximple_jugada[nJug][0].y);
	}

}
